/*
 * @Author: yixin 
 * @Date: 2018-07-09 15:10:24 
 * @Last Modified by:   yixin 
 * @Last Modified time: 2018-07-09 15:10:24 
 */
import { Component } from 'react';
import Storage from 'react-native-storage';
import { AsyncStorage } from 'react-native';
import async from './async';

let _storage;
let defaultExpires = 1000 * 3600 * 24;
let size = 1000;

export default class Cache extends Component {
  /**
   * 获取storage的对象
   */
  static getStorage() {
    if (!_storage) {
      _storage = new Storage({
        // 最大容量，默认值1000条数据循环存储
        size: size,

        // 存储引擎：对于RN使用AsyncStorage，对于web使用window.localStorage
        // 如果不指定则数据只会保存在内存中，重启后即丢失
        storageBackend: AsyncStorage,

        // 数据过期时间，默认一整天（1000 * 3600 * 24 毫秒），设为null则永不过期
        defaultExpires: defaultExpires,

        // 读写时在内存中缓存数据。默认启用。
        enableCache: true,

        // 如果storage中没有相应数据，或数据已过期，
        // 则会调用相应的sync方法，无缝返回最新数据。
        // sync方法的具体说明会在后文提到
        // 你可以在构造函数这里就写好sync的方法
        // 或是在任何时候，直接对storage.sync进行赋值修改
        // 或是写到另一个文件里，这里require引入
        // sync: require('你可以另外写一个文件专门处理sync')
        sync: async
      });
    }
    return _storage;
  }

  /**
   * storage是否初始化
   */
  static isInit() {
    if (!_storage) {
      // throw '请先调用_getStorage()进行初始化';
      this.getStorage();
    }
  }

  /**
   * 保存数据
   * key: 保存的key值
   * data: 保存的value
   * expires: 有效时间 (可选)
   */
  static save(key, data, expires = defaultExpires) {
    this.isInit();
    _storage.save({
      key: key,  // 注意:请不要在key中使用_下划线符号!
      data: data,
      // 如果不指定过期时间，则会使用defaultExpires参数
      // 如果设为null，则永不过期
      expires: defaultExpires
    });
    console.log(`save ${key} success!`);
  }

  /**
   * 查询数据
   * key: 查询的key值
   * cb: 查询成功后执行的方法  (可选)
   * fetchOptions: sync的额外参数  (可选)
   * someFlag: 根据syncParams中的额外参数做对应处理  (可选)
   */
  static load(key, fetchOptions = null, cb, someFlag = null) {
    this.isInit();
    const value =  _storage.load({
      key: key,

      // autoSync(默认为true)意味着在没有找到数据或数据过期时自动调用相应的sync方法
      autoSync: true,

      // syncInBackground(默认为true)意味着如果数据过期，
      // 在调用sync方法的同时先返回已经过期的数据。
      // 设置为false的话，则等待sync方法提供的最新数据(当然会需要更多时间)。
      syncInBackground: true,

      // 你还可以给sync方法传递额外的参数
      syncParams: {
        ...fetchOptions
      },
    }).then(ret => {
      cb && cb(ret);
      console.log(`load ${key} success! => ${ret}`);
      return ret;
    }).catch(err => {
    // 如果没有找到数据且没有sync方法，
    // 或者有其他异常，则在catch中返回
      console.log(err);
    });
    return value;
  }

  /**
   * key: 删除数据的key值
   */
  static remove(key) {
    this.isInit();
    _storage.remove({
      key: key
    });
  }

  static clearall() {
    this.remove('token');
    this.remove('userinfo');
  }

  // !! 清空map，移除所有"key-id"数据（但会保留只有key的数据）
  static clearMap() {
    this.isInit();
    _storage.clearMap();
  }


}